import path from "node:path"
import { ulid } from "ulid"
import fs from 'fs';

Bot.adapter.push(new class OneBotv11Adapter {
  id = "QQ"
  name = "OneBotv11"
  path = this.name
  echo = {}
  timeout = 60000

  /** 日志格式化 */
  makeLog(msg) {
    return Bot.String(msg).replace(/base64:\/\/.*?(,|]|")/g, "base64://...$1")
  }

  /** 发送 API 请求 */
  sendApi(data, ws, action, params = {}) {
    const echo = ulid()
    const request = { action, params, echo }
    ws.sendMsg(request)
    const error = Error()
    return new Promise((resolve, reject) =>
      this.echo[echo] = {
        request, resolve, reject, error,
        timeout: setTimeout(() => {
          reject(Object.assign(error, request, { timeout: this.timeout }))
          delete this.echo[echo]
          const errorMsg = `请求超时: ${action} - ${JSON.stringify(params).substring(0, 100)}...`
          Bot.makeLog("error", [errorMsg, request], data.self_id)
          ws.terminate()
        }, this.timeout),
      }
    )
  }

  /** 处理文件格式 */
  async makeFile(file, opts) {
    if (typeof file === 'string' && (file.startsWith('./') || file.startsWith('/') || file.startsWith('file://'))) {
      const filePath = file.replace('file://', '');
      const fileBuffer = await fs.promises.readFile(filePath);
      return `base64://${fileBuffer.toString('base64')}`;
    }
    file = await Bot.Buffer(file, {
      http: true, size: 10485760, ...opts,
    });
    if (Buffer.isBuffer(file))
      return `base64://${file.toString("base64")}`;
    return file;
  }

  /** 处理消息格式 */
  async makeMsg(msg) {
    if (!Array.isArray(msg))
      msg = [msg]
    const msgs = []
    const forward = []
    for (let i of msg) {
      if (typeof i !== "object")
        i = { type: "text", data: { text: i } }
      else if (!i.data)
        i = { type: i.type, data: { ...i, type: undefined } }

      switch (i.type) {
        case "at":
          if (i.data.qq === undefined || i.data.qq === null || i.data.qq === 0) {
            i.data.qq = i.data.id;
          }
          i.data.qq = String(i.data.qq)
          break
        case "reply":
          i.data.id = String(i.data.id)
          break
        case "button":
          continue
        case "node":
          forward.push(...i.data)
          continue
        case "raw":
          i = i.data
          break
        case "music":
          if (!i.data.type) i.data.type = "qq"
          break
        case "tts":
          if (i.data.text) {
            i.data.text = String(i.data.text)
          }
          break
        case "markdown":
          // 支持 Markdown 消息
          if (i.data.content) {
            i.data.content = String(i.data.content)
          }
          break
        case "poke":
          // 戳一戳消息
          if (i.data.id !== undefined) {
            i.data.qq = String(i.data.id)
          }
          break
      }

      if (i.data.file)
        i.data.file = await this.makeFile(i.data.file)

      msgs.push(i)
    }
    return [msgs, forward]
  }

  /** 发送消息（通用方法） */
  async sendMsg(msg, send, sendForwardMsg) {
    const [message, forward] = await this.makeMsg(msg)
    const ret = []

    if (forward.length) {
      const data = await sendForwardMsg(forward)
      if (Array.isArray(data))
        ret.push(...data)
      else
        ret.push(data)
    }

    if (message.length)
      ret.push(await send(message))
    if (ret.length === 1) return ret[0]

    const message_id = []
    for (const i of ret) if (i?.message_id)
      message_id.push(i.message_id)
    return { data: ret, message_id }
  }

  /** 发送好友消息 */
  sendFriendMsg(data, msg) {
    return this.sendMsg(msg, message => {
      Bot.makeLog("info", `发送好友消息：${this.makeLog(message)}`, `${data.self_id} => ${data.user_id}`, true)
      return data.bot.sendApi("send_private_msg", {
        user_id: data.user_id,
        message,
      })
    }, msg => this.sendFriendForwardMsg(data, msg))
  }

  /** 发送群消息 */
  sendGroupMsg(data, msg) {
    return this.sendMsg(msg, message => {
      Bot.makeLog("info", `发送群消息：${this.makeLog(message)}`, `${data.self_id} => ${data.group_id}`, true)
      return data.bot.sendApi("send_group_msg", {
        group_id: data.group_id,
        message,
      })
    }, msg => this.sendGroupForwardMsg(data, msg))
  }

  /** 发送频道消息 */
  sendGuildMsg(data, msg) {
    return this.sendMsg(msg, message => {
      Bot.makeLog("info", `发送频道消息：${this.makeLog(message)}`, `${data.self_id}] => ${data.guild_id}-${data.channel_id}`, true)
      return data.bot.sendApi("send_guild_channel_msg", {
        guild_id: data.guild_id,
        channel_id: data.channel_id,
        message,
      })
    }, msg => Bot.sendForwardMsg(msg => this.sendGuildMsg(data, msg), msg))
  }

  /** 撤回消息 */
  async recallMsg(data, message_id) {
    if (!Array.isArray(message_id))
      message_id = [message_id]
    const msgs = []
    for (const i of message_id)
      msgs.push(await data.bot.sendApi("delete_msg", { message_id: i }).catch(i => i))
    return msgs
  }

  /** 解析消息 */
  parseMsg(msg) {
    const array = []
    for (const i of Array.isArray(msg) ? msg : [msg])
      if (typeof i === "object")
        array.push({ ...i.data, type: i.type })
      else
        array.push({ type: "text", text: String(i) })
    return array
  }

  /** 获取消息 */
  async getMsg(data, message_id) {
    const msg = (await data.bot.sendApi("get_msg", { message_id })).data
    if (msg?.message)
      msg.message = this.parseMsg(msg.message)
    return msg
  }

  /** 获取好友消息历史记录 */
  async getFriendMsgHistory(data, message_seq, count) {
    const msgs = (await data.bot.sendApi("get_friend_msg_history", {
      user_id: data.user_id,
      message_seq,
      count,
    })).data?.messages

    for (const i of Array.isArray(msgs) ? msgs : [msgs])
      if (i?.message)
        i.message = this.parseMsg(i.message)
    return msgs
  }

  /** 获取群消息历史记录 */
  async getGroupMsgHistory(data, message_seq, count) {
    const msgs = (await data.bot.sendApi("get_group_msg_history", {
      group_id: data.group_id,
      message_seq,
      count,
    })).data?.messages

    for (const i of Array.isArray(msgs) ? msgs : [msgs])
      if (i?.message)
        i.message = this.parseMsg(i.message)
    return msgs
  }

  /** 获取转发消息 */
  async getForwardMsg(data, message_id) {
    const msgs = (await data.bot.sendApi("get_forward_msg", {
      message_id,
    })).data?.messages

    for (const i of Array.isArray(msgs) ? msgs : [msgs])
      if (i?.message)
        i.message = this.parseMsg(i.message || i.content)
    return msgs
  }

  /** 分割并发送转发消息 */
  async splitAndSendForward(sendFunc, data, messages, maxRetries = 3) {
    try {
      return await sendFunc(data, messages);
    } catch (error) {
      if (messages.length <= 1 || maxRetries <= 0) {
        throw error;
      }

      const mid = Math.ceil(messages.length / 2);
      const firstHalf = messages.slice(0, mid);
      const secondHalf = messages.slice(mid);

      Bot.makeLog("info", `转发消息发送失败，尝试拆分为 ${firstHalf.length} 和 ${secondHalf.length} 条消息重新发送`, data.self_id);

      const results = [];
      try {
        results.push(await this.splitAndSendForward(sendFunc, data, firstHalf, maxRetries - 1));
      } catch (e) {
        Bot.makeLog("error", `第一部分发送失败: ${e.message}`, data.self_id);
      }

      try {
        results.push(await this.splitAndSendForward(sendFunc, data, secondHalf, maxRetries - 1));
      } catch (e) {
        Bot.makeLog("error", `第二部分发送失败: ${e.message}`, data.self_id);
      }

      return results.filter(r => r);
    }
  }

  /** 构造转发消息 */
  async makeForwardMsg(msg) {
    const msgs = []
    for (const i of msg) {
      const [content, forward] = await this.makeMsg(i.message)
      if (forward.length)
        msgs.push(...await this.makeForwardMsg(forward))
      if (content.length)
        msgs.push({
          type: "node", data: {
            name: i.nickname || "匿名消息",
            uin: String(Number(i.user_id) || 80000000),
            content,
            time: i.time,
          }
        })
    }
    return msgs
  }

  /** 发送好友转发消息 */
  async sendFriendForwardMsg(data, msg) {
    Bot.makeLog("info", `发送好友转发消息：${this.makeLog(msg)}`, `${data.self_id} => ${data.user_id}`, true)
    const sendFunc = async (d, messages) => {
      // 尝试使用新版 API
      try {
        return await d.bot.sendApi("send_forward_msg", {
          user_id: d.user_id,
          messages: await this.makeForwardMsg(messages),
        })
      } catch (err) {
        // 回退到旧版 API
        return d.bot.sendApi("send_private_forward_msg", {
          user_id: d.user_id,
          messages: await this.makeForwardMsg(messages),
        })
      }
    }
    return this.splitAndSendForward(sendFunc, data, msg)
  }

  /** 发送群转发消息 */
  async sendGroupForwardMsg(data, msg) {
    Bot.makeLog("info", `发送群转发消息：${this.makeLog(msg)}`, `${data.self_id} => ${data.group_id}`, true)
    const sendFunc = async (d, messages) => {
      // 尝试使用新版 API
      try {
        return await d.bot.sendApi("send_forward_msg", {
          group_id: d.group_id,
          messages: await this.makeForwardMsg(messages),
        })
      } catch (err) {
        // 回退到旧版 API
        return d.bot.sendApi("send_group_forward_msg", {
          group_id: d.group_id,
          messages: await this.makeForwardMsg(messages),
        })
      }
    }
    return this.splitAndSendForward(sendFunc, data, msg)
  }

  /** 构造自定义转发消息 */
  async makeCustomForwardMsg(data, nodes) {
    Bot.makeLog("info", `构建自定义转发消息：${this.makeLog(nodes)}`, data.self_id, true)
    const processedNodes = nodes.map(node => ({
      user_id: node.user_id || data.self_id,
      nickname: node.nickname || data.bot.nickname,
      message: node.content || node.message || "",
      time: node.time || Math.floor(Date.now() / 1000)
    }))
    return await this.makeForwardMsg(processedNodes)
  }

  /** 获取好友数组 */
  async getFriendArray(data) {
    return (await data.bot.sendApi("get_friend_list")).data || []
  }

  /** 获取好友列表 */
  async getFriendList(data) {
    const array = []
    for (const { user_id } of await this.getFriendArray(data))
      array.push(user_id)
    return array
  }

  /** 获取好友映射 */
  async getFriendMap(data) {
    const map = new Map
    for (const i of await this.getFriendArray(data))
      map.set(i.user_id, i)
    data.bot.fl = map
    return map
  }

  /** 获取好友信息 */
  async getFriendInfo(data) {
    const info = (await data.bot.sendApi("get_stranger_info", {
      user_id: data.user_id,
    })).data
    data.bot.fl.set(data.user_id, info)
    return info
  }

  /** 获取陌生人信息 */
  async getStrangerInfo(data, user_id, no_cache = false) {
    return (await data.bot.sendApi("get_stranger_info", {
      user_id,
      no_cache
    })).data
  }

  /** 获取单向好友列表 */
  async getUnidirectionalFriendList(data) {
    Bot.makeLog("info", "获取单向好友列表", data.self_id)
    return (await data.bot.sendApi("get_unidirectional_friend_list")).data
  }

  /** 删除好友 */
  async deleteFriend(data) {
    Bot.makeLog("info", `删除好友：${data.user_id}`, data.self_id)
    return data.bot.sendApi("delete_friend", { 
      user_id: data.user_id,
      // NapCat 支持的参数
      friend_id: data.user_id 
    })
      .finally(this.getFriendMap.bind(this, data))
  }

  /** 删除单向好友 */
  async deleteUnidirectionalFriend(data, user_id) {
    Bot.makeLog("info", `删除单向好友：${user_id}`, data.self_id)
    return data.bot.sendApi("delete_unidirectional_friend", { user_id })
  }

  /** 获取群数组 */
  async getGroupArray(data) {
    const array = (await data.bot.sendApi("get_group_list")).data || []
    try {
      for (const guild of await this.getGuildArray(data))
        for (const channel of await this.getGuildChannelArray({
          ...data,
          guild_id: guild.guild_id,
        }))
          array.push({
            guild,
            channel,
            group_id: `${guild.guild_id}-${channel.channel_id}`,
            group_name: `${guild.guild_name}-${channel.channel_name}`,
          })
    } catch (err) {
      Bot.makeLog("error", `获取频道信息失败：${err.message}`, data.self_id)
    }
    return array
  }

  /** 获取群列表 */
  async getGroupList(data) {
    const array = []
    for (const { group_id } of await this.getGroupArray(data))
      array.push(group_id)
    return array
  }

  /** 获取群映射 */
  async getGroupMap(data) {
    const map = new Map
    for (const i of await this.getGroupArray(data))
      map.set(i.group_id, i)
    data.bot.gl = map
    return map
  }

  /** 获取群信息 */
  async getGroupInfo(data) {
    const info = (await data.bot.sendApi("get_group_info", {
      group_id: data.group_id,
      no_cache: false
    })).data
    data.bot.gl.set(data.group_id, info)
    return info
  }

  /** 获取群成员数组 */
  async getMemberArray(data) {
    return (await data.bot.sendApi("get_group_member_list", {
      group_id: data.group_id,
      no_cache: false
    })).data || []
  }

  /** 获取群成员列表 */
  async getMemberList(data) {
    const array = []
    for (const { user_id } of await this.getMemberArray(data))
      array.push(user_id)
    return array
  }

  /** 获取群成员映射 */
  async getMemberMap(data) {
    const map = new Map
    for (const i of await this.getMemberArray(data))
      map.set(i.user_id, i)
    data.bot.gml.set(data.group_id, map)
    return map
  }

  /** 获取所有群成员映射 */
  async getGroupMemberMap(data) {
    for (const [group_id, group] of await this.getGroupMap(data)) {
      if (group.guild) continue
      await this.getMemberMap({ ...data, group_id })
    }
  }

  /** 获取群成员信息 */
  async getMemberInfo(data) {
    const info = (await data.bot.sendApi("get_group_member_info", {
      group_id: data.group_id,
      user_id: data.user_id,
      no_cache: false
    })).data
    let gml = data.bot.gml.get(data.group_id)
    if (!gml) {
      gml = new Map
      data.bot.gml.set(data.group_id, gml)
    }
    gml.set(data.user_id, info)
    return info
  }

  /** 获取频道数组 */
  async getGuildArray(data) {
    return (await data.bot.sendApi("get_guild_list")).data || []
  }

  /** 获取频道信息 */
  async getGuildInfo(data) {
    return (await data.bot.sendApi("get_guild_meta_by_guest", {
      guild_id: data.guild_id,
    })).data
  }

  /** 获取频道子频道数组 */
  async getGuildChannelArray(data) {
    return (await data.bot.sendApi("get_guild_channel_list", {
      guild_id: data.guild_id,
    })).data || []
  }

  /** 获取频道子频道映射 */
  async getGuildChannelMap(data) {
    const map = new Map
    for (const i of await this.getGuildChannelArray(data))
      map.set(i.channel_id, i)
    return map
  }

  /** 获取频道成员数组 */
  async getGuildMemberArray(data) {
    Bot.makeLog("info", `获取频道成员数组：${data.guild_id}`, data.self_id)
    const array = []
    let next_token = ""
    while (true) {
      const list = (await data.bot.sendApi("get_guild_member_list", {
        guild_id: data.guild_id,
        next_token,
      })).data
      if (!list) break

      for (const i of list.members)
        array.push({
          ...i,
          user_id: i.tiny_id,
        })
      if (list.finished) break
      next_token = list.next_token
    }
    return array
  }

  /** 获取频道成员列表 */
  async getGuildMemberList(data) {
    const array = []
    for (const { user_id } of await this.getGuildMemberArray(data))
      array.push(user_id)
    return array
  }

  /** 获取频道成员映射 */
  async getGuildMemberMap(data) {
    const map = new Map
    for (const i of await this.getGuildMemberArray(data))
      map.set(i.user_id, i)
    data.bot.gml.set(data.group_id, map)
    return map
  }

  /** 获取频道成员信息 */
  async getGuildMemberInfo(data) {
    Bot.makeLog("info", `获取频道成员信息：${data.user_id}`, `${data.self_id} => ${data.guild_id}`)
    return (await data.bot.sendApi("get_guild_member_profile", {
      guild_id: data.guild_id,
      user_id: data.user_id,
    })).data
  }

  /** 设置个人资料 */
  setProfile(data, profile) {
    Bot.makeLog("info", `设置资料：${Bot.String(profile)}`, data.self_id)
    return data.bot.sendApi("set_qq_profile", profile)
  }

  /** 设置头像 */
  async setAvatar(data, file) {
    Bot.makeLog("info", `设置头像：${file}`, data.self_id)
    return data.bot.sendApi("set_qq_avatar", {
      file: await this.makeFile(file),
    })
  }

  /** 发送点赞 */
  sendLike(data, times) {
    Bot.makeLog("info", `点赞：${times}次`, `${data.self_id} => ${data.user_id}`, true)
    return data.bot.sendApi("send_like", {
      user_id: data.user_id,
      times,
    })
  }

  /** 设置群名 */
  setGroupName(data, group_name) {
    Bot.makeLog("info", `设置群名：${group_name}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_name", {
      group_id: data.group_id,
      group_name,
    })
  }

  /** 设置群头像 */
  async setGroupAvatar(data, file) {
    Bot.makeLog("info", `设置群头像：${file}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_portrait", {
      group_id: data.group_id,
      file: await this.makeFile(file),
    })
  }

  /** 设置群管理员 */
  setGroupAdmin(data, user_id, enable) {
    Bot.makeLog("info", `${enable ? "设置" : "取消"}群管理员：${user_id}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_admin", {
      group_id: data.group_id,
      user_id,
      enable,
    })
  }

  /** 设置群名片 */
  setGroupCard(data, user_id, card) {
    Bot.makeLog("info", `设置群名片：${card}`, `${data.self_id} => ${data.group_id}, ${user_id}`, true)
    return data.bot.sendApi("set_group_card", {
      group_id: data.group_id,
      user_id,
      card,
    })
  }

  /** 设置群头衔 */
  setGroupTitle(data, user_id, special_title, duration) {
    Bot.makeLog("info", `设置群头衔：${special_title} ${duration}`, `${data.self_id} => ${data.group_id}, ${user_id}`, true)
    return data.bot.sendApi("set_group_special_title", {
      group_id: data.group_id,
      user_id,
      special_title,
      duration,
    })
  }

  /** 群打卡 */
  sendGroupSign(data) {
    Bot.makeLog("info", "群打卡", `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("send_group_sign", {
      group_id: data.group_id,
    })
  }

  /** 禁言群成员 */
  setGroupBan(data, user_id, duration) {
    Bot.makeLog("info", `禁言群成员：${duration}秒`, `${data.self_id} => ${data.group_id}, ${user_id}`, true)
    return data.bot.sendApi("set_group_ban", {
      group_id: data.group_id,
      user_id,
      duration,
    })
  }

  /** 禁言匿名用户 */
  async setGroupAnonymousBan(data, group_id, anonymous_flag, duration) {
    Bot.makeLog("info", `禁言匿名用户：${anonymous_flag} ${duration}秒`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("set_group_anonymous_ban", {
      group_id,
      anonymous_flag,
      duration
    })
  }

  /** 设置群匿名 */
  async setGroupAnonymous(data, group_id, enable) {
    Bot.makeLog("info", `设置群匿名：${enable ? "启用" : "禁用"}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("set_group_anonymous", {
      group_id,
      enable
    })
  }

  /** 全员禁言 */
  setGroupWholeKick(data, enable) {
    Bot.makeLog("info", `${enable ? "开启" : "关闭"}全员禁言`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_whole_ban", {
      group_id: data.group_id,
      enable,
    })
  }

  /** 踢出群成员 */
  setGroupKick(data, user_id, reject_add_request) {
    Bot.makeLog("info", `踢出群成员${reject_add_request ? "拒绝再次加群" : ""}`, `${data.self_id} => ${data.group_id}, ${user_id}`, true)
    return data.bot.sendApi("set_group_kick", {
      group_id: data.group_id,
      user_id,
      reject_add_request,
    })
  }

  /** 退出群聊或解散群 */
  setGroupLeave(data, is_dismiss) {
    Bot.makeLog("info", is_dismiss ? "解散" : "退群", `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_leave", {
      group_id: data.group_id,
      is_dismiss,
    })
  }

  /** 下载文件 */
  async downloadFile(data, url, thread_count, headers) {
    Bot.makeLog("info", `下载文件：${url}`, data.self_id)
    return data.bot.sendApi("download_file", {
      url,
      thread_count,
      headers,
    })
  }

  /** 发送好友文件 */
  async sendFriendFile(data, file, name = path.basename(file)) {
    Bot.makeLog("info", `发送好友文件：${name}(${file})`, `${data.self_id} => ${data.user_id}`, true)
    return data.bot.sendApi("upload_private_file", {
      user_id: data.user_id,
      file: await this.makeFile(file, { file: true }),
      name,
    })
  }

  /** 发送群文件 */
  async sendGroupFile(data, file, folder, name = path.basename(file)) {
    Bot.makeLog("info", `发送群文件：${folder || ""}/${name}(${file})`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("upload_group_file", {
      group_id: data.group_id,
      folder,
      file: await this.makeFile(file, { file: true }),
      name,
    })
  }

  /** 删除群文件 */
  deleteGroupFile(data, file_id, busid) {
    Bot.makeLog("info", `删除群文件：${file_id}(${busid})`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("delete_group_file", {
      group_id: data.group_id,
      file_id,
      busid,
    })
  }

  /** 创建群文件文件夹 */
  createGroupFileFolder(data, name) {
    Bot.makeLog("info", `创建群文件夹：${name}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("create_group_file_folder", {
      group_id: data.group_id,
      name,
    })
  }

  /** 删除群文件文件夹 */
  deleteGroupFileFolder(data, folder_id) {
    Bot.makeLog("info", `删除群文件夹：${folder_id}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("delete_group_folder", {
      group_id: data.group_id,
      folder_id,
    })
  }

  /** 获取群文件系统信息 */
  async getGroupFileSystemInfo(data) {
    Bot.makeLog("info", `获取群文件系统信息：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_file_system_info", {
      group_id: data.group_id,
    })).data
  }

  /** 获取群文件列表 */
  async getGroupFiles(data, folder_id) {
    if (folder_id) {
      Bot.makeLog("info", `获取群子目录文件列表：${folder_id}`, `${data.self_id} => ${data.group_id}`)
      return (await data.bot.sendApi("get_group_files_by_folder", {
        group_id: data.group_id,
        folder_id,
      })).data
    }
    Bot.makeLog("info", `获取群根目录文件列表：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_root_files", {
      group_id: data.group_id,
    })).data
  }

  /** 获取群文件下载链接 */
  async getGroupFileUrl(data, file_id, busid) {
    Bot.makeLog("info", `获取群文件下载链接：${file_id}(${busid})`, `${data.self_id} => ${data.group_id}`)
    return (await data.bot.sendApi("get_group_file_url", {
      group_id: data.group_id,
      file_id,
      busid,
    })).data
  }

  /** 获取群文件操作对象 */
  getGroupFs(data) {
    return {
      upload: this.sendGroupFile.bind(this, data),
      rm: this.deleteGroupFile.bind(this, data),
      mkdir: this.createGroupFileFolder.bind(this, data),
      rmdir: this.deleteGroupFileFolder.bind(this, data),
      df: this.getGroupFileSystemInfo.bind(this, data),
      ls: this.getGroupFiles.bind(this, data),
      download: this.getGroupFileUrl.bind(this, data),
    }
  }

  /** 处理好友请求 */
  setFriendAddRequest(data, flag, approve, remark) {
    Bot.makeLog("info", `处理好友请求：${flag} ${approve ? "同意" : "拒绝"}`, data.self_id)
    return data.bot.sendApi("set_friend_add_request", {
      flag,
      approve,
      remark,
    })
  }

  /** 处理群请求 */
  setGroupAddRequest(data, flag, approve, reason, sub_type = "add") {
    Bot.makeLog("info", `处理群请求：${flag} ${approve ? "同意" : "拒绝"}`, `${data.self_id} => ${data.group_id}`)
    return data.bot.sendApi("set_group_add_request", {
      flag,
      sub_type,
      approve,
      reason,
    })
  }

  /** 获取群荣誉信息 */
  async getGroupHonorInfo(data) {
    Bot.makeLog("info", `获取群荣誉信息：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_honor_info", {
      group_id: data.group_id,
      type: "all"
    })).data
  }

  /** 获取精华消息列表 */
  async getEssenceMsgList(data) {
    Bot.makeLog("info", `获取精华消息列表：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_essence_msg_list", {
      group_id: data.group_id,
    })).data
  }

  /** 设置精华消息 */
  setEssenceMsg(data, message_id) {
    Bot.makeLog("info", `设置精华消息：${message_id}`, data.self_id)
    return data.bot.sendApi("set_essence_msg", { message_id })
  }

  /** 删除精华消息 */
  deleteEssenceMsg(data, message_id) {
    Bot.makeLog("info", `删除精华消息：${message_id}`, data.self_id)
    return data.bot.sendApi("delete_essence_msg", { message_id })
  }

  /** 获取登录信息 */
  async getLoginInfo(data) {
    Bot.makeLog("info", "获取登录信息", data.self_id)
    return (await data.bot.sendApi("get_login_info")).data
  }

  /** 获取状态 */
  async getStatus(data) {
    Bot.makeLog("info", "获取机器人状态", data.self_id)
    return (await data.bot.sendApi("get_status")).data
  }

  /** 重启服务 */
  async restartService(data) {
    Bot.makeLog("info", "重启 go-cqhttp", data.self_id)
    return data.bot.sendApi("set_restart")
  }

  /** 获取版本信息 */
  async getVersionInfo(data) {
    Bot.makeLog("info", "获取版本信息", data.self_id)
    return (await data.bot.sendApi("get_version_info")).data
  }

  /** 获取群公告 */
  async getGroupNotice(data) {
    Bot.makeLog("info", `获取群公告：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_notice", {
      group_id: data.group_id,
    })).data
  }

  /** 发送群公告 */
  async sendGroupNotice(data, content, image = "") {
    Bot.makeLog("info", `发送群公告：${content}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("_send_group_notice", {
      group_id: data.group_id,
      content,
      image: image ? await this.makeFile(image) : undefined,
    })
  }

  /** 删除群公告 */
  async deleteGroupNotice(data, notice_id) {
    Bot.makeLog("info", `删除群公告：${notice_id}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("delete_group_notice", {
      group_id: data.group_id,
      notice_id,
    })
  }

  /** 获取群 @全体成员 剩余次数 */
  async getGroupAtAllRemain(data) {
    Bot.makeLog("info", `获取@全体成员剩余次数：${data.group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_at_all_remain", {
      group_id: data.group_id,
    })).data
  }

  /** 获取群系统消息 */
  async getGroupSystemMsg(data) {
    Bot.makeLog("info", "获取群系统消息", data.self_id)
    return (await data.bot.sendApi("get_group_system_msg")).data
  }

  /** 检查是否可以发送图片 */
  async canSendImage(data) {
    Bot.makeLog("info", "检查是否可以发送图片", data.self_id)
    return (await data.bot.sendApi("can_send_image")).data?.yes
  }

  /** 检查是否可以发送语音 */
  async canSendRecord(data) {
    Bot.makeLog("info", "检查是否可以发送语音", data.self_id)
    return (await data.bot.sendApi("can_send_record")).data?.yes
  }

  /** 获取图片 OCR 结果 */
  async ocrImage(data, image) {
    Bot.makeLog("info", `获取图片 OCR 结果：${image}`, data.self_id)
    return (await data.bot.sendApi("ocr_image", {
      image: await this.makeFile(image),
    })).data
  }

  /** 获取中文分词 */
  async getWordSlices(data, content) {
    Bot.makeLog("info", `获取中文分词：${content}`, data.self_id)
    return (await data.bot.sendApi(".get_word_slices", { content })).data
  }

  /** 获取 Cookies */
  async getCookies(data, domain) {
    Bot.makeLog("info", `获取 Cookies：${domain}`, data.self_id)
    return (await data.bot.sendApi("get_cookies", { domain })).data
  }

  /** 获取 CSRF Token */
  async getCsrfToken(data) {
    Bot.makeLog("info", "获取 CSRF Token", data.self_id)
    return (await data.bot.sendApi("get_csrf_token")).data
  }

  /** 获取在线客户端列表 */
  async getOnlineClients(data, no_cache = false) {
    Bot.makeLog("info", "获取在线客户端列表", data.self_id)
    return (await data.bot.sendApi("get_online_clients", { no_cache })).data
  }

  /** 创建群 */
  async createGroup(data, name, members = []) {
    Bot.makeLog("info", `创建群：${name}`, data.self_id, true)
    const response = await data.bot.sendApi("_create_group", {
      name,
      initial_members: members,
    })
    await this.getGroupMap(data)
    return response.data
  }

  /** 标记消息已读 */
  async markMsgAsRead(data, message_id) {
    Bot.makeLog("info", `标记消息已读：${message_id}`, data.self_id)
    return data.bot.sendApi("mark_msg_as_read", { message_id })
  }

  /** 获取图片信息（新 API） */
  async getImage(data, file) {
    Bot.makeLog("info", `获取图片信息：${file}`, data.self_id)
    return (await data.bot.sendApi("get_image", { file })).data
  }

  /** 发送合并转发（新版 API） */
  async sendForwardMsg(data, messages) {
    Bot.makeLog("info", `发送合并转发消息`, data.self_id, true)
    return data.bot.sendApi("send_forward_msg", { messages })
  }

  /** 设置在线状态 */
  async setOnlineStatus(data, status, ext_status, battery_status) {
    Bot.makeLog("info", `设置在线状态：${status}`, data.self_id)
    return data.bot.sendApi("set_online_status", { 
      status,
      ext_status,
      battery_status
    })
  }

  /* ========== NapCat 扩展 API ========== */

  /** 群签到 */
  async setGroupSign(data) {
    Bot.makeLog("info", `群签到`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("set_group_sign", {
      group_id: data.group_id,
    })
  }

  /** 群聊戳一戳 */
  async groupPoke(data, user_id) {
    Bot.makeLog("info", `群聊戳一戳：${user_id}`, `${data.self_id} => ${data.group_id}`, true)
    return data.bot.sendApi("group_poke", {
      group_id: data.group_id,
      user_id,
    })
  }

  /** 私聊戳一戳 */
  async friendPoke(data, user_id) {
    Bot.makeLog("info", `私聊戳一戳：${user_id}`, `${data.self_id}`, true)
    return data.bot.sendApi("friend_poke", {
      user_id,
    })
  }

  /** 通用戳一戳 */
  async sendPoke(data, user_id, group_id) {
    if (group_id) {
      Bot.makeLog("info", `发送戳一戳（群）：${user_id}`, `${data.self_id} => ${group_id}`, true)
      return data.bot.sendApi("send_poke", {
        group_id,
        user_id,
      })
    } else {
      Bot.makeLog("info", `发送戳一戳（私聊）：${user_id}`, `${data.self_id}`, true)
      return data.bot.sendApi("send_poke", {
        user_id,
      })
    }
  }

  /** 获取推荐好友/群聊卡片 */
  async getArkSharePeer(data, user_id, phoneNumber, group_id) {
    if (user_id || phoneNumber) {
      Bot.makeLog("info", `获取推荐好友卡片：${user_id || phoneNumber}`, data.self_id)
      return (await data.bot.sendApi("ArkSharePeer", {
        user_id,
        phoneNumber: phoneNumber || "",
      })).data
    } else if (group_id) {
      Bot.makeLog("info", `获取推荐群聊卡片：${group_id}`, data.self_id)
      return (await data.bot.sendApi("ArkSharePeer", {
        group_id,
      })).data
    }
  }

  /** 获取推荐群聊卡片 */
  async getArkShareGroup(data, group_id) {
    Bot.makeLog("info", `获取推荐群聊卡片：${group_id}`, data.self_id)
    return (await data.bot.sendApi("ArkShareGroup", {
      group_id,
    })).data
  }

  /** 获取机器人账号范围 */
  async getRobotUinRange(data) {
    Bot.makeLog("info", `获取机器人账号范围`, data.self_id)
    return (await data.bot.sendApi("get_robot_uin_range")).data
  }

  /** 获取分类的好友列表 */
  async getFriendsWithCategory(data) {
    Bot.makeLog("info", `获取分类的好友列表`, data.self_id)
    return (await data.bot.sendApi("get_friends_with_category")).data
  }

  /** 获取文件信息 */
  async getFile(data, file_id) {
    Bot.makeLog("info", `获取文件信息：${file_id}`, data.self_id)
    return (await data.bot.sendApi("get_file", {
      file_id,
    })).data
  }

  /** 转发到私聊 */
  async forwardFriendSingleMsg(data, message_id, user_id) {
    Bot.makeLog("info", `转发到私聊：${message_id} => ${user_id}`, data.self_id, true)
    return data.bot.sendApi("forward_friend_single_msg", {
      message_id,
      user_id,
    })
  }

  /** 转发到群聊 */
  async forwardGroupSingleMsg(data, message_id, group_id) {
    Bot.makeLog("info", `转发到群聊：${message_id} => ${group_id}`, data.self_id, true)
    return data.bot.sendApi("forward_group_single_msg", {
      message_id,
      group_id,
    })
  }

  /** 英译中 */
  async translateEn2Zh(data, words) {
    Bot.makeLog("info", `英译中：${words.length}个词`, data.self_id)
    return (await data.bot.sendApi("translate_en2zh", {
      words,
    })).data
  }

  /** 设置表情回复 */
  async setMsgEmojiLike(data, message_id, emoji_id) {
    Bot.makeLog("info", `设置表情回复：${message_id} => ${emoji_id}`, data.self_id)
    return data.bot.sendApi("set_msg_emoji_like", {
      message_id,
      emoji_id,
    })
  }

  /** 设置私聊已读 */
  async markPrivateMsgAsRead(data, user_id) {
    Bot.makeLog("info", `设置私聊已读：${user_id}`, data.self_id)
    return data.bot.sendApi("mark_private_msg_as_read", {
      user_id,
    })
  }

  /** 设置群聊已读 */
  async markGroupMsgAsRead(data, group_id) {
    Bot.makeLog("info", `设置群聊已读：${group_id}`, data.self_id)
    return data.bot.sendApi("mark_group_msg_as_read", {
      group_id,
    })
  }

  /** 创建收藏 */
  async createCollection(data, content) {
    Bot.makeLog("info", `创建收藏`, data.self_id)
    return data.bot.sendApi("create_collection", content)
  }

  /** 获取收藏列表 */
  async getCollectionList(data) {
    Bot.makeLog("info", `获取收藏列表`, data.self_id)
    return (await data.bot.sendApi("get_collection_list")).data
  }

  /** 设置签名 */
  async setSelfLongnick(data, longNick) {
    Bot.makeLog("info", `设置签名：${longNick}`, data.self_id)
    return data.bot.sendApi("set_self_longnick", {
      longNick,
    })
  }

  /** 获取最近联系人 */
  async getRecentContact(data, count = 10) {
    Bot.makeLog("info", `获取最近联系人：${count}个`, data.self_id)
    return (await data.bot.sendApi("get_recent_contact", {
      count,
    })).data
  }

  /** 标记所有已读 */
  async markAllAsRead(data) {
    Bot.makeLog("info", `标记所有已读`, data.self_id)
    return data.bot.sendApi("_mark_all_as_read")
  }

  /** 获取自身点赞列表 */
  async getProfileLike(data) {
    Bot.makeLog("info", `获取自身点赞列表`, data.self_id)
    return (await data.bot.sendApi("get_profile_like")).data
  }

  /** 获取自定义表情 */
  async fetchCustomFace(data, count = 48) {
    Bot.makeLog("info", `获取自定义表情：${count}个`, data.self_id)
    return (await data.bot.sendApi("fetch_custom_face", {
      count,
    })).data
  }

  /** AI文字转语音 */
  async getAiRecord(data, character, group_id, text) {
    Bot.makeLog("info", `AI文字转语音：${character} - ${text}`, data.self_id)
    return (await data.bot.sendApi("get_ai_record", {
      character,
      group_id,
      text,
    })).data
  }

  /** 获取AI语音角色列表 */
  async getAiCharacters(data, group_id, chat_type) {
    Bot.makeLog("info", `获取AI语音角色列表：${group_id}`, data.self_id)
    return (await data.bot.sendApi("get_ai_characters", {
      group_id,
      chat_type,
    })).data
  }

  /** 群聊发送AI语音 */
  async sendGroupAiRecord(data, character, group_id, text) {
    Bot.makeLog("info", `群聊发送AI语音：${character} - ${text}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("send_group_ai_record", {
      character,
      group_id,
      text,
    })
  }

  /** 获取群文件数量 */
  async getGroupFileCount(data, group_id) {
    Bot.makeLog("info", `获取群文件数量：${group_id}`, data.self_id)
    return (await data.bot.sendApi("get_group_file_count", {
      group_id,
    })).data
  }

  /** 获取群文件列表 */
  async getGroupFileList(data, group_id, folder_id) {
    Bot.makeLog("info", `获取群文件列表：${group_id}${folder_id ? ` 文件夹：${folder_id}` : ''}`, data.self_id)
    return (await data.bot.sendApi("get_group_file_list", {
      group_id,
      folder_id,
    })).data
  }

  /** 设置群文件文件夹 */
  async setGroupFileFolder(data, group_id, folder_name) {
    Bot.makeLog("info", `创建群文件夹：${folder_name}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("set_group_file_folder", {
      group_id,
      folder_name,
    })
  }

  /** 删除群文件 */
  async delGroupFile(data, group_id, file_id) {
    Bot.makeLog("info", `删除群文件：${file_id}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("del_group_file", {
      group_id,
      file_id,
    })
  }

  /** 删除群文件夹 */
  async delGroupFileFolder(data, group_id, folder_id) {
    Bot.makeLog("info", `删除群文件夹：${folder_id}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("del_group_file_folder", {
      group_id,
      folder_id,
    })
  }

  /** 获取已过滤好友申请 */
  async getDoubtFriendsAddRequest(data) {
    Bot.makeLog("info", `获取已过滤好友申请`, data.self_id)
    return (await data.bot.sendApi("get_doubt_friends_add_request")).data
  }

  /** 设置已过滤好友申请 */
  async setDoubtFriendsAddRequest(data, request_id, approve) {
    Bot.makeLog("info", `处理已过滤好友申请：${request_id} ${approve ? "同意" : "拒绝"}`, data.self_id)
    return data.bot.sendApi("set_doubt_friends_add_request", {
      request_id,
      approve,
    })
  }

  /** go-cqhttp扩展的上传群文件 */
  async goCQHTTPUploadGroupFile(data, group_id, file, name, folder_id) {
    Bot.makeLog("info", `上传群文件到文件夹：${name} => ${folder_id || "根目录"}`, `${data.self_id} => ${group_id}`, true)
    return data.bot.sendApi("upload_group_file", {
      group_id,
      file: await this.makeFile(file, { file: true }),
      name,
      folder_id,
    })
  }

  /** 选择好友对象 */
  pickFriend(data, user_id) {
    const i = {
      ...data.bot.fl.get(user_id),
      ...data,
      user_id,
    }
    return {
      ...i,
      sendMsg: this.sendFriendMsg.bind(this, i),
      getMsg: this.getMsg.bind(this, i),
      recallMsg: this.recallMsg.bind(this, i),
      getForwardMsg: this.getForwardMsg.bind(this, i),
      sendForwardMsg: this.sendFriendForwardMsg.bind(this, i),
      sendFile: this.sendFriendFile.bind(this, i),
      getInfo: this.getFriendInfo.bind(this, i),
      getAvatarUrl() { return this.avatar || `https://q.qlogo.cn/g?b=qq&s=0&nk=${user_id}` },
      getChatHistory: this.getFriendMsgHistory.bind(this, i),
      thumbUp: this.sendLike.bind(this, i),
      delete: this.deleteFriend.bind(this, i),
      markMsgAsRead: (message_id) => this.markMsgAsRead(i, message_id),
      markAsRead: () => this.markPrivateMsgAsRead(i, user_id),
      poke: () => this.friendPoke(i, user_id),
      forwardMsg: (message_id) => this.forwardFriendSingleMsg(i, message_id, user_id),
    }
  }

  /** 选择群成员对象 */
  pickMember(data, group_id, user_id) {
    if (typeof group_id === "string" && group_id.match("-")) {
      const guild_id = group_id.split("-")
      const i = {
        ...data,
        guild_id: guild_id[0],
        channel_id: guild_id[1],
        user_id,
      }
      return {
        ...this.pickGroup(i, group_id),
        ...i,
        getInfo: this.getGuildMemberInfo.bind(this, i),
        getAvatarUrl: async () => (await this.getGuildMemberInfo(i)).avatar_url,
      }
    }

    const i = {
      ...data.bot.gml.get(group_id)?.get(user_id),
      ...data,
      group_id,
      user_id,
    }
    return {
      ...this.pickFriend(i, user_id),
      ...i,
      getInfo: this.getMemberInfo.bind(this, i),
      getAvatarUrl() { return this.avatar || `https://q.qlogo.cn/g?b=qq&s=0&nk=${user_id}` },
      poke: () => this.groupPoke({ ...data, group_id }, user_id),
      mute: this.setGroupBan.bind(this, i, user_id),
      kick: this.setGroupKick.bind(this, i, user_id),
      setCard: (card) => this.setGroupCard(i, user_id, card),
      setTitle: (title, duration) => this.setGroupTitle(i, user_id, title, duration),
      setAdmin: (enable = true) => this.setGroupAdmin(i, user_id, enable),
      get is_friend() { return data.bot.fl.has(user_id) },
      get is_owner() { return this.role === "owner" },
      get is_admin() { return this.role === "admin" || this.is_owner },
    }
  }

  /** 选择群对象 */
  pickGroup(data, group_id) {
    if (typeof group_id === "string" && group_id.match("-")) {
      const guild_id = group_id.split("-")
      const i = {
        ...data.bot.gl.get(group_id),
        ...data,
        guild_id: guild_id[0],
        channel_id: guild_id[1],
      }
      return {
        ...i,
        sendMsg: this.sendGuildMsg.bind(this, i),
        getMsg: this.getMsg.bind(this, i),
        recallMsg: this.recallMsg.bind(this, i),
        getForwardMsg: this.getForwardMsg.bind(this, i),
        getInfo: this.getGuildInfo.bind(this, i),
        getChannelArray: this.getGuildChannelArray.bind(this, i),
        getChannelMap: this.getGuildChannelMap.bind(this, i),
        getMemberArray: this.getGuildMemberArray.bind(this, i),
        getMemberList: this.getGuildMemberList.bind(this, i),
        getMemberMap: this.getGuildMemberMap.bind(this, i),
        pickMember: this.pickMember.bind(this, i),
      }
    }

    const i = {
      ...data.bot.gl.get(group_id),
      ...data,
      group_id,
    }
    return {
      ...i,
      sendMsg: this.sendGroupMsg.bind(this, i),
      getMsg: this.getMsg.bind(this, i),
      recallMsg: this.recallMsg.bind(this, i),
      getForwardMsg: this.getForwardMsg.bind(this, i),
      sendForwardMsg: this.sendGroupForwardMsg.bind(this, i),
      sendFile: (file, name, folder_id) => {
        if (folder_id) {
          return this.goCQHTTPUploadGroupFile(i, group_id, file, name, folder_id)
        }
        return this.sendGroupFile(i, file, undefined, name)
      },
      getInfo: this.getGroupInfo.bind(this, i),
      getAvatarUrl() { return this.avatar || `https://p.qlogo.cn/gh/${group_id}/${group_id}/0` },
      getChatHistory: this.getGroupMsgHistory.bind(this, i),
      getHonorInfo: this.getGroupHonorInfo.bind(this, i),
      getEssenceList: this.getEssenceMsgList.bind(this, i),
      setEssence: this.setEssenceMsg.bind(this, i),
      deleteEssence: this.deleteEssenceMsg.bind(this, i),
      getMemberArray: this.getMemberArray.bind(this, i),
      getMemberList: this.getMemberList.bind(this, i),
      getMemberMap: this.getMemberMap.bind(this, i),
      pickMember: this.pickMember.bind(this, i, group_id),
      pokeMember: qq => this.groupPoke(i, qq),
      setName: this.setGroupName.bind(this, i),
      setAvatar: this.setGroupAvatar.bind(this, i),
      setAdmin: this.setGroupAdmin.bind(this, i),
      setCard: this.setGroupCard.bind(this, i),
      setTitle: this.setGroupTitle.bind(this, i),
      sign: () => this.setGroupSign(i),
      muteMember: this.setGroupBan.bind(this, i),
      muteAll: this.setGroupWholeKick.bind(this, i),
      muteAnonymous: (anonymous_flag, duration) => this.setGroupAnonymousBan(i, group_id, anonymous_flag, duration),
      setAnonymous: (enable) => this.setGroupAnonymous(i, group_id, enable),
      kickMember: this.setGroupKick.bind(this, i),
      quit: this.setGroupLeave.bind(this, i),
      fs: this.getGroupFs(i),
      getNotice: () => this.getGroupNotice(i),
      sendNotice: (content, image) => this.sendGroupNotice(i, content, image),
      deleteNotice: (notice_id) => this.deleteGroupNotice(i, notice_id),
      getAtAllRemain: () => this.getGroupAtAllRemain(i),
      markAsRead: () => this.markGroupMsgAsRead(i, group_id),
      setEmojiLike: (message_id, emoji_id) => this.setMsgEmojiLike(i, message_id, emoji_id),
      forwardMsg: (message_id) => this.forwardGroupSingleMsg(i, message_id, group_id),
      getArkShareCard: () => this.getArkShareGroup(i, group_id),
      getFileCount: () => this.getGroupFileCount(i, group_id),
      getFileList: (folder_id) => this.getGroupFileList(i, group_id, folder_id),
      createFolder: (folder_name) => this.setGroupFileFolder(i, group_id, folder_name),
      deleteFile: (file_id) => this.delGroupFile(i, group_id, file_id),
      deleteFolder: (folder_id) => this.delGroupFileFolder(i, group_id, folder_id),
      getAiCharacters: (chat_type) => this.getAiCharacters(i, group_id, chat_type),
      getAiRecord: (character, text) => this.getAiRecord(i, character, group_id, text),
      sendAiRecord: (character, text) => this.sendGroupAiRecord(i, character, group_id, text),
      get is_owner() { return data.bot.gml.get(group_id)?.get(data.self_id)?.role === "owner" },
      get is_admin() { return data.bot.gml.get(group_id)?.get(data.self_id)?.role === "admin" || this.is_owner },
    }
  }

  /** 连接初始化 */
  async connect(data, ws) {
    Bot[data.self_id] = {
      adapter: this,
      ws: ws,
      sendApi: this.sendApi.bind(this, data, ws),
      stat: {
        start_time: data.time,
        stat: {},
        get lost_pkt_cnt() { return this.stat.packet_lost },
        get lost_times() { return this.stat.lost_times },
        get recv_msg_cnt() { return this.stat.message_received },
        get recv_pkt_cnt() { return this.stat.packet_received },
        get sent_msg_cnt() { return this.stat.message_sent },
        get sent_pkt_cnt() { return this.stat.packet_sent },
      },
      model: "XRK Yunzai",

      info: {},
      get uin() { return this.info.user_id },
      get nickname() { return this.info.nickname },
      get avatar() { return `https://q.qlogo.cn/g?b=qq&s=0&nk=${this.uin}` },

      setProfile: this.setProfile.bind(this, data),
      setNickname: nickname => this.setProfile(data, { nickname }),
      setAvatar: this.setAvatar.bind(this, data),
      setOnlineStatus: (status, ext_status, battery_status) => this.setOnlineStatus(data, status, ext_status, battery_status),
      setSignature: longnick => this.setSelfLongnick(data, longnick),

      pickFriend: this.pickFriend.bind(this, data),
      get pickUser() { return this.pickFriend },
      getFriendArray: this.getFriendArray.bind(this, data),
      getFriendList: this.getFriendList.bind(this, data),
      getFriendMap: this.getFriendMap.bind(this, data),
      getFriendsWithCategory: this.getFriendsWithCategory.bind(this, data),
      fl: new Map,

      pickMember: this.pickMember.bind(this, data),
      pickGroup: this.pickGroup.bind(this, data),
      getGroupArray: this.getGroupArray.bind(this, data),
      getGroupList: this.getGroupList.bind(this, data),
      getGroupMap: this.getGroupMap.bind(this, data),
      getGroupMemberMap: this.getGroupMemberMap.bind(this, data),
      gl: new Map,
      gml: new Map,

      request_list: [],
      getSystemMsg() { return this.request_list },
      setFriendAddRequest: this.setFriendAddRequest.bind(this, data),
      setGroupAddRequest: this.setGroupAddRequest.bind(this, data),
      getDoubtFriendsAddRequest: this.getDoubtFriendsAddRequest.bind(this, data),
      setDoubtFriendsAddRequest: this.setDoubtFriendsAddRequest.bind(this, data),

      setEssenceMessage: this.setEssenceMsg.bind(this, data),
      removeEssenceMessage: this.deleteEssenceMsg.bind(this, data),

      cookies: {},
      getCookies: this.getCookies.bind(this, data),
      getCsrfToken: this.getCsrfToken.bind(this, data),

      getLoginInfo: this.getLoginInfo.bind(this, data),
      getStatus: this.getStatus.bind(this, data),
      getVersion: this.getVersionInfo.bind(this, data),
      restart: this.restartService.bind(this, data),
      getGroupSystemMsg: this.getGroupSystemMsg.bind(this, data),
      canSendImage: this.canSendImage.bind(this, data),
      canSendRecord: this.canSendRecord.bind(this, data),
      ocrImage: this.ocrImage.bind(this, data),
      getWordSlices: this.getWordSlices.bind(this, data),
      getOnlineClients: this.getOnlineClients.bind(this, data),
      getStrangerInfo: this.getStrangerInfo.bind(this, data),
      getImage: this.getImage.bind(this, data),
      getFile: this.getFile.bind(this, data),
      downloadFile: this.downloadFile.bind(this, data),
      createGroup: this.createGroup.bind(this, data),
      getRecentContact: this.getRecentContact.bind(this, data),
      markAllAsRead: this.markAllAsRead.bind(this, data),
      getProfileLike: this.getProfileLike.bind(this, data),
      createCollection: this.createCollection.bind(this, data),
      getCollectionList: this.getCollectionList.bind(this, data),
      fetchCustomFace: this.fetchCustomFace.bind(this, data),
      translateEn2Zh: this.translateEn2Zh.bind(this, data),
      getRobotUinRange: this.getRobotUinRange.bind(this, data),
      sendPoke: (user_id, group_id) => this.sendPoke(data, user_id, group_id),
      getArkSharePeer: (user_id, phoneNumber, group_id) => this.getArkSharePeer(data, user_id, phoneNumber, group_id),
    }
    data.bot = Bot[data.self_id]

    if (!Bot.uin.includes(data.self_id))
      Bot.uin.push(data.self_id)

    data.bot.sendApi("_set_model_show", {
      model: data.bot.model,
      model_show: data.bot.model,
    }).catch(() => { })

    data.bot.info = (await data.bot.sendApi("get_login_info").catch(i => i.error)).data
    data.bot.guild_info = (await data.bot.sendApi("get_guild_service_profile").catch(i => i.error)).data
    data.bot.clients = (await data.bot.sendApi("get_online_clients").catch(i => i.error)).data?.clients
    data.bot.version = {
      ...(await data.bot.sendApi("get_version_info").catch(i => i.error)).data,
      id: this.id,
      name: this.name,
      get version() {
        return this.app_full_name || `${this.app_name} v${this.app_version}`
      },
    }

    data.bot.status = (await data.bot.sendApi("get_status").catch(i => i.error)).data || {}

    if (data.bot.cookies["qun.qq.com"] = (
      await data.bot.sendApi("get_cookies", { domain: "qun.qq.com" }).catch(i => i.error)
    )?.cookies) for (const i of ["aq", "connect", "docs", "game", "gamecenter", "haoma", "id", "kg", "mail", "mma", "office", "openmobile", "qqweb", "qzone", "ti", "v", "vip", "y"]) {
      const domain = `${i}.qq.com`
      data.bot.cookies[domain] = await data.bot.sendApi("get_cookies", { domain })
        .then(i => i.data?.cookies).catch(i => i.error)
    }
    data.bot.bkn = (await data.bot.sendApi("get_csrf_token").catch(i => i.error))?.token

    data.bot.getFriendMap()
    data.bot.getGroupMemberMap()

    Bot.makeLog("mark", `${this.name}(${this.id}) ${data.bot.version.version} 已连接`, data.self_id)
    Bot.em(`connect.${data.self_id}`, data)
  }

  /** 处理消息事件 */
  makeMessage(data) {

    data.message = this.parseMsg(data.message)
    switch (data.message_type) {
      case "private": {
        const name = data.sender.card || data.sender.nickname || data.bot.fl.get(data.user_id)?.nickname
        Bot.makeLog("info", `好友消息：${name ? `[${name}] ` : ""}${data.raw_message}`, `${data.self_id} <= ${data.user_id}`, true)
        break
      } case "group": {
        const group_name = data.group_name || data.bot.gl.get(data.group_id)?.group_name
        let user_name = data.sender.card || data.sender.nickname
        if (!user_name) {
          const user = data.bot.gml.get(data.group_id)?.get(data.user_id) || data.bot.fl.get(data.user_id)
          if (user) user_name = user?.card || user?.nickname
        }
        Bot.makeLog("info", `群消息：${user_name ? `[${group_name ? `${group_name}, ` : ""}${user_name}] ` : ""}${data.raw_message}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        break
      } case "guild":
        data.message_type = "group"
        data.group_id = `${data.guild_id}-${data.channel_id}`
        Bot.makeLog("info", `频道消息：[${data.sender.nickname}] ${Bot.String(data.message)}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        Object.defineProperty(data, "friend", { get() { return this.member || {} } })
        break
      default:
        Bot.makeLog("warn", `未知消息：${logger.magenta(data.raw)}`, data.self_id)
    }

    Bot.em(`${data.post_type}.${data.message_type}.${data.sub_type}`, data)
  }

  /** 处理通知事件 */
  async makeNotice(data) {
    switch (data.notice_type) {
      case "friend_recall":
        Bot.makeLog("info", `好友消息撤回：${data.message_id}`, `${data.self_id} <= ${data.user_id}`, true)
        break
      case "group_recall":
        Bot.makeLog("info", `群消息撤回：${data.operator_id} => ${data.user_id} ${data.message_id}`, `${data.self_id} <= ${data.group_id}`, true)
        break
      case "group_increase": {
        Bot.makeLog("info", `群成员增加：${data.operator_id} => ${data.user_id} ${data.sub_type}`, `${data.self_id} <= ${data.group_id}`, true)
        const group = data.bot.pickGroup(data.group_id)
        group.getInfo()
        if (data.user_id === data.self_id)
          group.getMemberMap()
        else
          group.pickMember(data.user_id).getInfo()
        break
      } case "group_decrease": {
        Bot.makeLog("info", `群成员减少：${data.operator_id} => ${data.user_id} ${data.sub_type}`, `${data.self_id} <= ${data.group_id}`, true)
        if (data.user_id === data.self_id) {
          data.bot.gl.delete(data.group_id)
          data.bot.gml.delete(data.group_id)
        } else {
          data.bot.pickGroup(data.group_id).getInfo()
          data.bot.gml.get(data.group_id)?.delete(data.user_id)
        }
        break
      } case "group_admin":
        Bot.makeLog("info", `群管理员变动：${data.sub_type}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        data.set = data.sub_type === "set"
        data.bot.pickMember(data.group_id, data.user_id).getInfo()
        break
      case "group_upload":
        Bot.makeLog("info", `群文件上传：${Bot.String(data.file)}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        Bot.em("message.group.normal", {
          ...data,
          post_type: "message",
          message_type: "group",
          sub_type: "normal",
          message: [{ ...data.file, type: "file" }],
          raw_message: `[文件：${data.file.name}]`,
        })
        break
      case "group_ban":
        Bot.makeLog("info", `群禁言：${data.operator_id} => ${data.user_id} ${data.sub_type} ${data.duration}秒`, `${data.self_id} <= ${data.group_id}`, true)
        data.bot.pickMember(data.group_id, data.user_id).getInfo()
        break
      case "group_msg_emoji_like":
        Bot.makeLog("info", [`群消息回应：${data.message_id}`, data.likes], `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        break
      case "friend_add":
        Bot.makeLog("info", "好友添加", `${data.self_id} <= ${data.user_id}`, true)
        data.bot.pickFriend(data.user_id).getInfo()
        break
      case "notify":
        if (data.group_id)
          data.notice_type = "group"
        else
          data.notice_type = "friend"
        switch (data.sub_type) {
          case "poke":
            data.operator_id = data.user_id
            if (data.group_id)
              Bot.makeLog("info", `群戳一戳：${data.operator_id} => ${data.target_id}`, `${data.self_id} <= ${data.group_id}`, true)
            else
              Bot.makeLog("info", `好友戳一戳：${data.operator_id} => ${data.target_id}`, data.self_id)
            break
          case "honor":
            Bot.makeLog("info", `群荣誉：${data.honor_type}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
            data.bot.pickMember(data.group_id, data.user_id).getInfo()
            break
          case "title":
            Bot.makeLog("info", `群头衔：${data.title}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
            data.bot.pickMember(data.group_id, data.user_id).getInfo()
            break
          case "input_status":
            data.post_type = "internal"
            data.notice_type = "input"
            data.end ??= data.event_type !== 1
            data.message ||= data.status_text || `对方${data.end ? "结束" : "正在"}输入...`
            Bot.makeLog("info", data.message, `${data.self_id} <= ${data.user_id}`, true)
            break
          default:
            Bot.makeLog("warn", `未知通知：${logger.magenta(data.raw)}`, data.self_id)
        }
        break
      case "group_card":
        Bot.makeLog("info", `群名片更新：${data.card_old} => ${data.card_new}`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        data.bot.pickMember(data.group_id, data.user_id).getInfo()
        break
      case "offline_file":
        Bot.makeLog("info", `离线文件：${Bot.String(data.file)}`, `${data.self_id} <= ${data.user_id}`, true)
        Bot.em("message.private.friend", {
          ...data,
          post_type: "message",
          message_type: "private",
          sub_type: "friend",
          message: [{ ...data.file, type: "file" }],
          raw_message: `[文件：${data.file.name}]`,
        })
        break
      case "client_status":
        Bot.makeLog("info", `客户端${data.online ? "上线" : "下线"}：${Bot.String(data.client)}`, data.self_id)
        data.clients = (await data.bot.sendApi("get_online_clients")).data?.clients
        data.bot.clients = data.clients
        break
      case "essence":
        data.notice_type = "group_essence"
        Bot.makeLog("info", `群精华消息：${data.operator_id} => ${data.sender_id} ${data.sub_type} ${data.message_id}`, `${data.self_id} <= ${data.group_id}`, true)
        break
      case "guild_channel_recall":
        Bot.makeLog("info", `频道消息撤回：${data.operator_id} => ${data.user_id} ${data.message_id}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}`, true)
        break
      case "message_reactions_updated":
        data.notice_type = "guild_message_reactions_updated"
        Bot.makeLog("info", `频道消息表情贴：${data.message_id} ${Bot.String(data.current_reactions)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`, true)
        break
      case "channel_updated":
        data.notice_type = "guild_channel_updated"
        Bot.makeLog("info", `子频道更新：${Bot.String(data.old_info)} => ${Bot.String(data.new_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`, true)
        break
      case "channel_created":
        data.notice_type = "guild_channel_created"
        Bot.makeLog("info", `子频道创建：${Bot.String(data.channel_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`, true)
        data.bot.getGroupMap()
        break
      case "channel_destroyed":
        data.notice_type = "guild_channel_destroyed"
        Bot.makeLog("info", `子频道删除：${Bot.String(data.channel_info)}`, `${data.self_id} <= ${data.guild_id}-${data.channel_id}, ${data.user_id}`, true)
        data.bot.getGroupMap()
        break
      case "bot_offline":
        data.post_type = "system"
        data.notice_type = "offline"
        Bot.makeLog("info", `${data.tag || "账号下线"}：${data.message}`, data.self_id)
        Bot.sendMasterMsg(`[${data.self_id}] ${data.tag || "账号下线"}：${data.message}`)
        break
      default:
        Bot.makeLog("warn", `未知通知：${logger.magenta(data.raw)}`, data.self_id)
    }

    let notice = data.notice_type.split("_")
    data.notice_type = notice.shift()
    notice = notice.join("_")
    if (notice)
      data.sub_type = notice

    if (data.guild_id && data.channel_id) {
      data.group_id = `${data.guild_id}-${data.channel_id}`
      Object.defineProperty(data, "friend", { get() { return this.member || {} } })
    }

    Bot.em(`${data.post_type}.${data.notice_type}.${data.sub_type}`, data)
  }

  /** 处理请求事件 */
  makeRequest(data) {
    switch (data.request_type) {
      case "friend":
        Bot.makeLog("info", `加好友请求：${data.comment}(${data.flag})`, `${data.self_id} <= ${data.user_id}`, true)
        data.sub_type = "add"
        data.approve = function (approve, remark) { return this.bot.setFriendAddRequest(this.flag, approve, remark) }
        break
      case "group":
        Bot.makeLog("info", `加群请求：${data.sub_type} ${data.comment}(${data.flag})`, `${data.self_id} <= ${data.group_id}, ${data.user_id}`, true)
        data.approve = function (approve, reason) { return this.bot.setGroupAddRequest(this.flag, approve, reason, this.sub_type) }
        break
      default:
        Bot.makeLog("warn", `未知请求：${logger.magenta(data.raw)}`, data.self_id)
    }

    data.bot.request_list.push(data)
    Bot.em(`${data.post_type}.${data.request_type}.${data.sub_type}`, data)
  }

  /** 处理心跳事件 */
  heartbeat(data) {
    if (data.status)
      Object.assign(data.bot.stat, data.status)

    if (data.status) {
      data.bot.status = {
        ...data.bot.status,
        ...data.status
      }
    }
  }

  /** 处理元事件 */
  makeMeta(data, ws) {
    switch (data.meta_event_type) {
      case "heartbeat":
        this.heartbeat(data)
        break
      case "lifecycle":
        this.connect(data, ws)
        break
      default:
        Bot.makeLog("warn", `未知消息：${logger.magenta(data.raw)}`, data.self_id)
    }
  }

  /** 处理 WebSocket 消息 */
  message(data, ws) {
    try {
      data = {
        ...JSON.parse(data),
        raw: Bot.String(data),
      }
    } catch (err) {
      return Bot.makeLog("error", ["解码数据失败", data, err])
    }

    if (data.post_type) {
      if (data.meta_event_type !== "lifecycle" && !Bot.uin.includes(data.self_id)) {
        Bot.makeLog("warn", `找不到对应Bot，忽略消息：${logger.magenta(data.raw)}`, data.self_id)
        return false
      }
      data.bot = Bot[data.self_id]

      switch (data.post_type) {
        case "meta_event":
          this.makeMeta(data, ws)
          break
        case "message":
          this.makeMessage(data)
          break
        case "notice":
          this.makeNotice(data)
          break
        case "request":
          this.makeRequest(data)
          break
        case "message_sent":
          data.post_type = "message"
          this.makeMessage(data)
          break
        default:
          Bot.makeLog("warn", `未知消息：${logger.magenta(data.raw)}`, data.self_id)
      }
    } else if (data.echo && this.echo[data.echo]) {
      if (![0, 1].includes(data.retcode))
        this.echo[data.echo].reject(Object.assign(
          this.echo[data.echo].error,
          this.echo[data.echo].request,
          { error: data },
        ))
      else
        this.echo[data.echo].resolve(data.data ? new Proxy(data, {
          get: (target, prop) => target.data[prop] ?? target[prop],
        }) : data)
      clearTimeout(this.echo[data.echo].timeout)
      delete this.echo[data.echo]
    } else {
      Bot.makeLog("warn", `未知消息：${logger.magenta(data.raw)}`, data.self_id)
    }
  }

  /** 加载适配器 */
  load() {
    for (const i of [this.path, "go-cqhttp"]) {
      if (!Array.isArray(Bot.wsf[i]))
        Bot.wsf[i] = []
      Bot.wsf[i].push((ws, ...args) =>
        ws.on("message", data => this.message(data, ws, ...args))
      )
    }
  }
})